/*====================================================================================
# «ДЭНСИ:РМК» module of «ДЭНСИ: КАССА» complex is the front-office application for POS-systems based on fiscal registrators.
# © OOO "DNC Trade" 2009, Authors: Savitskaya Alexandra, Pavlova Irina(Pavlova_Irina@shtrih-s.ru), Sukhanova Anna (anuta.s13@gmail.com), Savrasov Alexandr.
# This is a FREE software, licensed under GNU/GPL terms. See details in LICENSING_ENG.TXT in main directory
#====================================================================================
# Модуль «ДЭНСИ:РМК» программного комплекса «ДЭНСИ: КАССА» - рабочее место кассира для POS-систем на базе фискальных регистраторов
# © ООО "ДЭНСИ Трейд" 2009, Авторы: Савицкая Александра, Павлова Ирина(Pavlova_Irina@shtrih-s.ru), Суханова Анна (anuta.s13@gmail.com), Саврасов Александр.
# Данная программа является свободным программным обеспечением, выпускается на условиях Стандартной Общественной Лицензии GNU/GPL
# Подробнее смотрите в файле LICENSING_RUS.TXT в основной директории
#====================================================================================*/
/*====================================================================================
# «ДЭНСИ:РМК» module of «ДЭНСИ: КАССА» complex is the front-office application for POS-systems based on fiscal registrators.
# © OOO "DNC Trade" 2009, Authors: Savitskaya Alexandra, Pavlova Irina(Pavlova_Irina@shtrih-s.ru), Sukhanova Anna (anuta.s13@gmail.com), Savrasov Alexandr.
# This is a FREE software, licensed under GNU/GPL terms. See details in LICENSING_ENG.TXT in main directory
#====================================================================================
# Модуль «ДЭНСИ:РМК» программного комплекса «ДЭНСИ: КАССА» - рабочее место кассира для POS-систем на базе фискальных регистраторов
# © ООО "ДЭНСИ Трейд" 2009, Авторы: Савицкая Александра, Павлова Ирина(Pavlova_Irina@shtrih-s.ru), Суханова Анна (anuta.s13@gmail.com), Саврасов Александр.
# Данная программа является свободным программным обеспечением, выпускается на условиях Стандартной Общественной Лицензии GNU/GPL
# Подробнее смотрите в файле LICENSING_RUS.TXT в основной директории
#====================================================================================*/
/*====================================================================================
# «ДЭНСИ:РМК» module of «ДЭНСИ: КАССА» complex is the front-office application for POS-systems based on fiscal registrators.
# © OOO "DNC Trade" 2009, Authors: Savitskaya Alexandra, Pavlova Irina(Pavlova_Irina@shtrih-s.ru), Sukhanova Anna (anuta.s13@gmail.com), Savrasov Alexandr.
# This is a FREE software, licensed under GNU/GPL terms. See details in LICENSING_ENG.TXT in main directory
#====================================================================================
# Модуль «ДЭНСИ:РМК» программного комплекса «ДЭНСИ: КАССА» - рабочее место кассира для POS-систем на базе фискальных регистраторов
# © ООО "ДЭНСИ Трейд" 2009, Авторы: Савицкая Александра, Павлова Ирина(Pavlova_Irina@shtrih-s.ru), Суханова Анна (anuta.s13@gmail.com), Саврасов Александр.
# Данная программа является свободным программным обеспечением, выпускается на условиях Стандартной Общественной Лицензии GNU/GPL
# Подробнее смотрите в файле LICENSING_RUS.TXT в основной директории
#====================================================================================*/
#include "addwarecontroller.h"

#include "authorization.h"
#include "setup_param.h"
#include "reg_pgsql.h"
#include "statestore.h"
#include "receipt.h"
#include "cdsp.h"
#include "addon_func.h"
#include "hwsrv.h"
#include "const.h"

#include <qstring.h>
#include <qtextcodec.h>

#include <iostream>

using namespace std;

#define GETRIGHT(right) Authorization::GetInstance()->GetRight(right)

extern SP sp;
extern Registration Reg;
extern Receipt * receipt;
extern HWSRV *hw;


AddWareController AddWareController::instance;

//======================================================================//
AddWareController::AddWareController(QWidget *parent, const char * name) : QObject((QObject *)parent, name)
{
//puts("AddWareController::AddWareController(QWidget *parent, const char *name)");
  quantity = 1;
}

//======================================================================//
AddWareController * AddWareController::GetInstance()
{
//puts("AddWareController * AddWareController::GetInstance()");
  return &instance;
}

//======================================================================//
double AddWareController::GetQuantity()
{
//puts("double AddWareController::GetQuantity()");
  return quantity;
}

//======================================================================//
// parental - источник ввода количества. 0 - клавиатурный воод, 1 - устройство
//
void AddWareController::SetQuantity(double q, int parental)
{
    
    
    if ( StateStore::GetInstance()->GetSessionState() == BLOCKED )    emit Error(74);
    if ( StateStore::GetInstance()->GetViewState() == REC )    emit Error(45);
    else if ( StateStore::GetInstance()->GetReceiptState() == COPY )    emit Error(36);
    else  {
	quantity = Round(q * 1000) / 1000;
	if  ((quantity < 0.001) || (quantity > 9999999.999) )     {
	    emit Error(55);
	    quantity = 1;
	}
	emit QuantitySet(quantity, parental);
    }
}
//======================================================================//
void AddWareController::EscapeQuantity()
{
//puts("void AddWareController::EscapeQuantity()");
  quantity = 1;
}
/*
//======================================================================//
void AddWareController::ClearModel()
{
puts("void AddWareController::ClearModel()");
  receipt->Clear_Receipt();
}*/

//======================================================================//
//  code - строка кода или штрих-кода товара
//  code_type - признак ш.к./кода true - штрих-код,  false - код
//  parental - источник ввода кода. 0 - клавиатурный воод, 1 - сканер, 2 - визуадьный подбор
int AddWareController::AddWare(const char * code, bool code_type, int parental)
{
    //printf("AddWareController::AddWare(code = %s, code_type = %d, parental = %d)\n", code, code_type, parental);
    //puts("void AddWareController::AddWare(const char * code_str, bool code_type, int parental)");
    /*  if(receipt->GetStateofClosing())  {
             puts("clear");
            ClearModel();
     } */
    
    
    //закончилось время смены
    if ( StateStore::GetInstance()->GetSessionState() == BLOCKED )  {	emit Error(74);		return -1;    }
    
    //копия чека
    if ( StateStore::GetInstance()->GetReceiptState() == COPY ) {	emit Error(36);		return -2;    }       
    
    // начисдка на чекдка на чек
    if ( StateStore::GetInstance()->GetViewState() == REC ) {
	if ( StateStore::GetInstance()->GetViewState() != INS && StateStore::GetInstance()->GetViewState() != INS_TEXT ) 	
	    emit Error(45);
	return -3;	
    }
    
    // Проверка правильности ввода кода с клавиатуры
    if ( ((parental == 0) && CheckCode(code, code_type)) || (parental != 0) )   {
	
	// Права доступа проверили
	if ( GetAccess(code_type, parental) )     {
	    int index = -1;
	    
	    Reg.internal_tmp = quantity;
	    
	    int er = AddNewPosition(code, code_type, index);
	    
	    //printf("AddNewPosition(code = %s, code_type = %d, index = %d ) return %d \n", code, code_type, index, er);
	    if (er != 0)  {
		//emit Error(er);	
		if ( er == 3 || er == 12 ) {
		    if ( StateStore::GetInstance()->GetViewState() != INS && StateStore::GetInstance()->GetViewState() != INS_TEXT )  
			emit Error(er);  
		    return er;
		}
		emit Error(er);
		return er;		
	    }
	    
	    bool newsellreceipt = false;
	    
	    if ( (StateStore::GetInstance()->GetReceiptState() !=RETURN) && (StateStore::GetInstance()->GetReceiptState() != SELL) ) {
		StateStore::GetInstance()->SetReceiptState(SELL);
		newsellreceipt = true;
	    }
	    
	    
	    
	    //puts("############################");
	    emit WareAdded(index, code_type, newsellreceipt);
	    //puts("############################");
	    
	    PositionCustomerDisplay(index);
	    EscapeQuantity();
	    
	}	
    }
    return 0;
}

//##############################--PRIVATE--SECTION--##########################################//

//======================================================================//
bool AddWareController::AuthorizationRequest(int r)
{
//puts("bool AddWareController::AuthorizationRequest(int r)");
  bool result = Authorization::GetInstance()->RequestWithRight(r);
  if(result)
    emit AuthRequest();
  return result;
}

//======================================================================//
bool AddWareController::GetAccess(bool code_type, int parental)
{
//puts("bool AddWareController::GetAccess(bool code_type, int parental)");
  bool access_flag = true;
  
  //мозгоимение ((( 
  
  if((parental == 1) && !GETRIGHT(1)) // Регистрация сканером ш.-к.
    access_flag = AuthorizationRequest(1);

  else if((parental == 2) && !GETRIGHT(3)) // Регистрация через визуальный подбор
    access_flag = AuthorizationRequest(3);

  else if((parental == 0) && code_type && !GETRIGHT(2)) // Регистрация ш.-к. с клавиатуры
    access_flag = AuthorizationRequest(2);

  else if((parental == 0) && !code_type && !GETRIGHT(0)) // Регистрация по внутреннему коду
    access_flag = AuthorizationRequest(0);
  
  if(!access_flag)
    emit Error(72);

  return access_flag;
}

//======================================================================//
bool AddWareController::CheckCode(const char * code, bool code_type)
{
    //puts("bool AddWareController::CheckCode(bool code_type)	");
    //проверка штрих-кода
    if ( code_type && (strlen(code) > MAXLENBARCODE) )   {
	emit Error(54);
	return false;
    }	
    /*
    if ( !code_type )  {
	QString s = code;
	bool nf = true;
	int id = s.toInt(&nf);
	if ( !nf )    {
	    emit Error(56);
	    return false;
	}
    }*/
    return true;
}

//======================================================================//
/*//code - код товара (внутренний или штрих-)
//code_type : true - использовать штрих-код товара, false - исрпользовать внутренний код товара
//npos : позиция чека, в которую будет добавлен товар
//returns : 
//0 - все нормально
//1 - продажа данного товара запрещена в карточке товара
//2 - возврат данного товара запрещен в карточке товара
//3 - не верный штрих-код товара 
//4 - не верный код товара
//5 - нет требуемого количества товара
//6 - не верное имя товара в БД 
//7 - запрос в БД не был выполнен, смотреть логфайл
//8 - попытка продать штучный товар как весосой
//9 - истек срок годности
//10 - переполнение при умножении
//11 - переполнение при сложении
//12 - не верный весовой штрих-код товара, товар с указанным кодом не найден*/
  
int AddWareController::AddNewPosition(const char *code, bool code_type, int & npos)  
{
    //puts("int AddWareController::AddNewPosition(bool code_type, int & npos)");

  int result = 0;
  
  //printf("AddNewPosition (code = %s quantity = %f) \n", code, quantity);
  
  if ( StateStore::GetInstance()->GetReceiptState() == RETURN ) {
     //puts("receipt state = RETURN \n");
     result = Reg.New_Receipt_Record(code, quantity, receipt, code_type, true, false, npos);
  } else {
     //puts("reseipt state = not RETURN");
     result = Reg.New_Receipt_Record(code, quantity, receipt, code_type, false, false, npos);
  }
  
  if ( (result == 0) && (npos == receipt->record_num - 1) )    Reg.Add_Taxes(receipt, npos);
  return result; 
  
}

//=====================================================================//
void AddWareController::PositionCustomerDisplay(int pos)
{
  //puts("void AddWareController::PositionCustomerDisplay(int pos)");
  if(sp.cdsp_detalize_product)
  {
    QTextCodec * DbCodec, * HwCodec;
    DbCodec = QTextCodec::codecForName(DBCODEC);
    HwCodec = QTextCodec::codecForName(HWCODEC);
      
    double price = receipt->GetPosElemRef(pos)->GetPrice();
    double sum = Round(quantity * price * 100) / 100;
    double total = receipt->Sum() - receipt->RecalculationDiscounts();
    
    QString prod_name, p_str, q_str, sum_str, total_str;
    
    prod_name = HwCodec->fromUnicode(DbCodec->toUnicode(receipt->GetPosElemRef(pos)->GetLongtitle()));
    p_str.setNum(price, 'f', 2);
    q_str.setNum(quantity, 'f', 3);
    sum_str.setNum(sum, 'f', 2);
    total_str.setNum(total, 'f', 2);
    
//const char * name_str, const char * price_str, const char * quant_str, const char * sum_str, const char * total_str, HWSRV * hw_ref
    CDSP cdsp(prod_name.ascii(), p_str.ascii(), q_str.ascii(), sum_str.ascii(), total_str.ascii(), hw);
    cdsp.RegistrationPositionCustomerDisplay();
  }
}


